﻿using MediatR;
using S.Common.ApiResult;
using S.Parturition.Domain;
using S.Parturition.Infrastructure.Interface;
using S.Parturition.Read.API.Application.Command;
using S.Parturition.Read.API.Dto;

namespace S.Parturition.Read.API.Application.CommandHandlers
{
    public class GetParturitionListHandler : IRequestHandler<GetParturitionListCommand, ApiResult<List<ParturitionListDto>>>
    {

        private readonly IParturitionRepository parturition;

        private readonly MyDbContext dbContext;

        public GetParturitionListHandler(IParturitionRepository parturition, MyDbContext dbContext)
        {
            this.parturition = parturition;
            this.dbContext = dbContext;
        }


        public async Task<ApiResult<List<ParturitionListDto>>> Handle(GetParturitionListCommand request, CancellationToken cancellationToken)
        {
            var list = await parturition.GetAllAsync();

            //查询条件
            if (!string.IsNullOrWhiteSpace(request.StateDate) && !string.IsNullOrWhiteSpace(request.EndDate))
            {
                list = list.Where(x => x.DeliveryDate > Convert.ToDateTime(request.StateDate) && x.DeliveryDate <= Convert.ToDateTime(request.EndDate).AddDays(1)).ToList();
            }
            if (!string.IsNullOrWhiteSpace(request.MonthEITag))
            {
                list = list.Where(x => x.EarTag.Contains(request.MonthEITag)).ToList();
            }
            if (!string.IsNullOrWhiteSpace(request.BroodNumber))
            {
                list = list.Where(x => x.BroodNumber.Contains(request.BroodNumber)).ToList();
            }
            if (request.UserId != 0)
            {
                list = list.Where(x => x.UserId == request.UserId).ToList();
            }
            if (!string.IsNullOrEmpty(request.TurnOutBuild))
            {
                list = list.Where(x => x.TurnOutBuild == request.TurnOutBuild).ToList();
            }
            if (!string.IsNullOrEmpty(request.ShiftToBuild))
            {
                list = list.Where(x => x.ShiftToBuild == request.ShiftToBuild).ToList();
            }

            var parturitionsWithLambs = from p in list
                                        join l in dbContext.LambRegistrationModel on p.EarTag equals l.MotherEar into lambGroup
                                        select new
                                        {
                                            Parturition = p,
                                            HealthyCount = lambGroup.Count(lamb => lamb.BirthState == 1),
                                            LambNumberCount = lambGroup.Count(lamb => lamb.BirthState == 2),
                                            DeformityCount = lambGroup.Count(lamb => lamb.BirthState == 3),
                                            StillbirthsCount = lambGroup.Count(lamb => lamb.BirthState == 4),
                                            MummyCount = lambGroup.Count(lamb => lamb.BirthState == 5),
                                            FreaksCount = lambGroup.Count(lamb => lamb.BirthState == 6),
                                            LitterSum = lambGroup.Sum(lamb => lamb.BirthWeight),
                                            LambNumberTotal = lambGroup.Count(),
                                            LiveWeight = lambGroup.Where(x => x.BirthState == 1 || x.BirthState == 2).Sum(x => x.BirthWeight),
                                            DeadWeight = lambGroup.Where(x => x.BirthState == 4).Sum(x => x.BirthWeight),
                                        };

            List<ParturitionListDto> parturitions = parturitionsWithLambs.Select(x => new ParturitionListDto
            {
                ParturitionId = x.Parturition.ParturitionId,
                UserId = x.Parturition.UserId,
                SheepStatus = x.Parturition.SheepStatus,
                EarTag = x.Parturition.EarTag,
                DeliveryDate = x.Parturition.DeliveryDate,
                GestationDays = x.Parturition.GestationDays,
                DifficultyDelivery = x.Parturition.DifficultyDelivery,
                FatSheep = x.Parturition.FatSheep,
                Motherhood = x.Parturition.Motherhood,
                Lactation = x.Parturition.Lactation,
                Mastitis = x.Parturition.Mastitis,
                BroodNumber = x.Parturition.BroodNumber,
                LambTotal = x.LambNumberTotal,
                LiveLambWeight = x.LiveWeight,
                DeadLambWeight = x.DeadWeight,
                HealthyNumber = x.HealthyCount,
                LambNumber = x.LambNumberCount,
                DeformityNumber = x.DeformityCount,
                StillbirthsNumber = x.StillbirthsCount,
                MummyNumber = x.MummyCount,
                FreaksNumber = x.FreaksCount,
                LiveNumber = x.HealthyCount + x.LambNumberCount,
                LitterWeight = x.LitterSum,
                Sex = x.Parturition.Sex,
                TurnOutBuild = x.Parturition.TurnOutBuild,
                TurnOutHuts = x.Parturition.TurnOutHuts,
                ShiftToBuild = x.Parturition.ShiftToBuild,
                ShiftToHuts = x.Parturition.ShiftToHuts,
                CreateBy = x.Parturition.CreateBy,
                CreateDate = x.Parturition.CreateDate,
                UpdateBy = x.Parturition.UpdateBy,
                UpdateDate = x.Parturition.UpdateDate,
                Auditor = x.Parturition.Auditor,
                AuditTime = x.Parturition.AuditTime,
                DocumentNumber = x.Parturition.DocumentNumber,
                SerialNumber = x.Parturition.SerialNumber,
            }).ToList();

            ApiResult<List<ParturitionListDto>> result = new ApiResult<List<ParturitionListDto>>();

            //总页数、总条数
            int totalCount = parturitions.Count;
            int pageCount = (int)Math.Ceiling(totalCount * 1.0 / request.PageSize);

            result.totalCount = totalCount;
            result.pageCount = pageCount;

            // 对列表进行分页处理
            result.Data = parturitions.Skip((request.PageIndex - 1) * request.PageSize).Take(request.PageSize).OrderByDescending(x => x.CreateDate).ToList();

            return result;
        }
    }
}
